

public class EvenOdd {
	public static volatile int cnt = 0;
	public static volatile boolean firstRun = true;
	public static Object lockinstance = "lock";
	public static void main(String[] args) {
		
		Even e = new Even(lockinstance);
		Odd o = new Odd(lockinstance);
		Thread et = new Thread(e);
		Thread ot = new Thread(o);

		et.start();
		ot.start();
	}

}

class Even implements Runnable{
	private Object lock;
	public Even(Object lock){
		this.lock = lock;
	}
	@Override
	public void run() {
		while(true){
			EvenOdd.cnt++;
			if(	EvenOdd.cnt %2 == 0 ){
				System.out.println(Thread.currentThread().getName()+" - "+EvenOdd.cnt);
			}
			if(EvenOdd.cnt >= 100){
				synchronized(lock){lock.notify();}
				break;
			}
			if(EvenOdd.cnt%10 == 0){
				synchronized(lock){
					lock.notify();
					try {
						System.out.println(Thread.currentThread().getName()+" Waiting");
						lock.wait();
						System.out.println(Thread.currentThread().getName()+" Running");
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}
		System.out.println(Thread.currentThread().getName()+" Completing");
	}
	
}

class Odd implements Runnable{
	private Object lock;
	public Odd(Object lock){
		this.lock = lock;
	}

	@Override
	public void run() {

		if(EvenOdd.firstRun ){
			try {
				synchronized(lock){
					EvenOdd.firstRun = false;
					lock.wait();
				}

			} catch (InterruptedException e1) {
				e1.printStackTrace();
			}
		}

		while(true){
			EvenOdd.cnt++;
			if(	EvenOdd.cnt %2 != 0 ){
				System.out.println(Thread.currentThread().getName()+" - "+EvenOdd.cnt);
			}
			if(EvenOdd.cnt >= 100){
				synchronized(lock){lock.notify();}
				break;
			}
			if(EvenOdd.cnt%10 == 0){
				try {
					synchronized(lock){
						lock.notify();
						System.out.println(Thread.currentThread().getName()+" Waiting");
						lock.wait();
						System.out.println(Thread.currentThread().getName()+" Running");
					}
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
		System.out.println(Thread.currentThread().getName()+" Completing");
	}
}